package crawler.client.core;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import crawler.client.core.handle.PathHandle;
import crawler.client.sdk.task.java.CrawlerExtractInfo;
import crawler.client.sdk.task.java.CrawlerTaskInfo;
import crawler.protocol.CrawlerClientProtocol;
import crawler.protocol.CrawlerServerProtocol;
import crawler.protocol.client.ClientInheritTask;
import crawler.protocol.client.ClientOriginTask;
import crawler.protocol.client.ClientTaskProtocol;
import crawler.protocol.server.ServerTaskConfigure;
import crawler.protocol.server.ServerTaskInfo;
import crawler.protocol.server.ServerTaskProtocol;

@Service
public class Execute {
	
	private static Logger log = LoggerFactory.getLogger(Execute.class);
	
	@Autowired
	private PathHandle pathHandle;
	
	private static final String START_METHOD = "crawler";
	private static final String SUFFIX = ".jar";
	private static final String HYPHENATION = "-";
	
	
	
	public void crawler(String[] args) {
		log.info("Client Run");
		
		//TODO 服务端获取
		CrawlerServerProtocol crawlerServerProtocol = connectServer();
		CrawlerClientProtocol crawlerClientProtocol = new CrawlerClientProtocol();
		
		
		ServerTaskConfigure configure= crawlerServerProtocol.getTasks().get(0).getConfigure();
		ServerTaskInfo taskInfo = crawlerServerProtocol.getTasks().get(0).getTaskInfo();
		
		
		String clientException = null;
		Object methodInvokeObj = null;
		Integer statusCode = null;
		String statusMsg = null;
		
		try {
			
			String groupName = configure.getGroupName();
			String version = configure.getVersion();
			Integer scriptType = configure.getScriptType();
			
			String scriptPath = pathHandle.getScriptPath(scriptType);

	
			String scriptFileName = groupName + HYPHENATION + version + SUFFIX;
			
			String taskName = configure.getTaskName();

			System.out.println(scriptPath);
			log.info(scriptPath);
			
			File scriptFile = new File(scriptPath + scriptFileName);
			URL url = scriptFile.toURI().toURL();
			
			CrawlerTaskInfo crawlerTaskInfo = new CrawlerTaskInfo();
			try {
				BeanUtils.copyProperties(crawlerTaskInfo, taskInfo);
			} catch (IllegalAccessException e1) {
				e1.printStackTrace();
			} catch (InvocationTargetException e1) {
				e1.printStackTrace();
			}

			
			ClassLoader loader = new URLClassLoader(new URL[] { url });// 创建类加载器
			Class<?> cls = loader.loadClass(taskName);
			Method method = cls.getMethod(START_METHOD, CrawlerTaskInfo.class);// 方法名和对应的各个参数的类型

			methodInvokeObj = method.invoke(null, crawlerTaskInfo);// 调用得到的上边的方法method
//			System.out.println(methodInvokeObj);
//			log.info(methodInvokeObj.toString());
			
		} catch (MalformedURLException e) {
			clientException = e.getMessage().substring(0, 1000);
			statusCode = 11;
			statusMsg = "启动脚本异常";
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		
		List<ClientTaskProtocol> tasks = new ArrayList<ClientTaskProtocol>();
		ClientTaskProtocol clientTaskProtocol = new ClientTaskProtocol();
		
		ClientOriginTask originTask = new ClientOriginTask();
		
		if (clientException != null) {
			originTask.setClientException(clientException);
		}
		if (statusCode != null) {
			originTask.setStatusCode(statusCode);
		}
		if (statusMsg != null) {
			originTask.setStatusMsg(statusMsg);
		}
		
		clientTaskProtocol.setOriginTask(originTask);
		
		crawlerClientProtocol.setTasks(tasks);
	}
	
	
//	private static String buildClientProtocol(Object methodInvokeObj,ClientOriginTask originTask,List<ClientInheritTask> inheritTasks) {
//		String clientStr = ClientUtil.collectClientInfo();
//		
//		JSONObject protocol_client = new JSONObject();
//		protocol_client.put("client", clientStr);
//		
//		JSONObject tasks = new JSONObject();
//
//		String data = null;
//		Integer statusCode = null;
//		String statusMsg = null;
//		
//		// 构建protocol_client协议
//		if (methodInvokeObj instanceof CrawlerExtractInfo) {
//			CrawlerExtractInfo multiCrawlerTaskResult = (CrawlerExtractInfo) methodInvokeObj;
//			List<CrawlerTaskInfo> crawlerTaskInfos = multiCrawlerTaskResult.getCrawlerTaskInfos();
//
//			if (crawlerTaskInfos != null && crawlerTaskInfos.size() > 0) {
//				JSONArray inheritTasks = new JSONArray();
//				String groupName = originTask.getGroupName();
//				String inheritParentUrl = originTask.getTaskUrl();
//				Boolean runNow = false;
//				
//				for (CrawlerTaskInfo task : crawlerTaskInfos) {
//
//					JSONObject protocol = new JSONObject();
//					
//					if (task.getGroupName() != null && !"".equals(task.getGroupName())) {
//						groupName = task.getGroupName();
//					}
//					
//					if (task.getRunNow() != null) {
//						runNow = task.getRunNow();
//					}
//					
//					String taskName = task.getTaskName();
//					String taskUrl = task.getChildUrl();
//					String information = task.getInformation();
//					
//					
//					//后面覆盖前面
//					data = task.getData();
//					statusCode = task.getStatusCode();
//					statusMsg = task.getStatusMsg();
//					
//					
//					protocol.put("groupName", groupName);
//					protocol.put("taskName", taskName);
//					protocol.put("taskUrl", taskUrl);
//					protocol.put("parentUrl", inheritParentUrl);
//					protocol.put("information;", information);
//					protocol.put("runNow", runNow);
//
//					inheritTasks.add(protocol);
//
//				}
//
//				tasks.put("inheritTasks", inheritTasks);
//
//			}
//
//		}
//		
//		originTask.setData(data);
//		if (statusCode != null) {
//			originTask.setStatusCode(statusCode);
//		}
//		if (statusMsg != null) {
//			originTask.setStatusMsg(statusMsg);
//		}
//		
//		
//		return protocol_client.toJSONString();
//	}
	
	

	
	private static CrawlerServerProtocol connectServer() {
		CrawlerServerProtocol crawlerServerProtocol = new CrawlerServerProtocol();
		List<ServerTaskProtocol> tasks = new ArrayList<ServerTaskProtocol>();
		
		ServerTaskConfigure configure= new ServerTaskConfigure();
		ServerTaskInfo taskInfo = new ServerTaskInfo();
		
		ServerTaskProtocol serverTaskProtocol = new ServerTaskProtocol();
	
		configure.setGroupName("www.a.com");
		configure.setTaskName("crawler.script.TestMuti");
		configure.setParentUrl("test.com");
		configure.setTaskId("1");
		configure.setVersion("0.0.1-SNAPSHOT");
		configure.setScriptType(1);
		
		JSONObject info = new JSONObject();
		info.put("cityId", 010);
		info.put("cityName", "北京");
		
		taskInfo.setInformation(info.toJSONString());
		
		
		serverTaskProtocol.setConfigure(configure);
		serverTaskProtocol.setTaskInfo(taskInfo);
		
		tasks.add(serverTaskProtocol);
		
		crawlerServerProtocol.setTasks(tasks);
		return crawlerServerProtocol;
	}
}
